/**
 * 为泛型集合提供基类。
 * License: BSD
 * Authors: Lucifer (786325481@QQ.com)
 * Copyright: Copyright (C) 2008 Lucifer. All rights reserved.
 */
module system.collections.objectmodel.ListCollection;

import system.Exception;
import system.collections.IList;
import system.collections.ICollection;
import system.collections.IEnumerable;
import system.collections.IEnumerator;
import system.collections.ArrayList;

/**
 * 为泛型集合提供基类。
 */
public class ListCollection(T) : IList!(T), ICollection!(T), IEnumerable!(T)
{
	private IList!(T) theList;

	public this()
	{
		this.theList = new ArrayList!(T)();
	}

	public this( IList!(T) list )
	in
	{
		assert( list !is null );
	}
	body
	{
		theList = list;
	}

	/* ***************************************************
	 * 实现ICollection(T)接口
	 * ***************************************************/
	public final bool isEmpty()
	{
		return theList.isEmpty();
	}

	public final int count()
	{
		return theList.count();
	}

	public final bool isReadOnly()
	{
		return theList.isReadOnly();
	}

	public final void add( T item )
	{
		auto index = theList.count;
		insertItem(index, item);
	}

	public final void clear()
	{
		clearItem();
	}

	protected void clearItem()
	{
		theList.clear();
	}

	public final bool contains(T item)
	{
		return this.theList.contains(item);
	} 

	public final void copyTo(T[] array)
	in
	{
		assert( array !is null );
	}
	body
	{
		return this.theList.copyTo(array);
	}

	public final bool remove(T item)
	{
		if( theList.isReadOnly() )
			throw new NotSupportedException();
		auto index = indexOf(item);
		if(index < 0)
			return false;
		this.removeAt(index);
		return true;
	}

	/* ********************************************************
	 * 实现IEnumerable(T)接口
	 * ********************************************************/
	public final IEnumerator!(T) getEnumerator()
	{
		return theList.getEnumerator();
	}

	public final int opApply (int delegate (ref T value) dg)
	{
		return theList.opApply(dg);
	}

	/* *********************************************************
	 * 实现IList(T)接口
	 * *********************************************************/
	public final T opIndex(int index)
	{
		return theList.opIndex(index);
	}

	public final void opIndexAssign(T item, int index)
	in
	{
		assert( index >= 0 || index < theList.count );
	}
	body
	{
		if( theList.isReadOnly() )
			throw new NotSupportedException();
		this.setItem(index, item);
	}

	protected void setItem(int index, T item)
	{
		theList[index] = item;
	}

	public final int indexOf(T item)
	{
		return this.theList.indexOf(item);
	}

	public final void insert(int index, T item)
	{
		insertItem(index, item);
	}
	
	protected void insertItem(int index, T item)
	{
		theList.insert(index, item);
	}

	public final void removeAt(int index)
	in
	{
		assert( index >= 0 || index < theList.count );
	}
	body
	{
		if( theList.isReadOnly() )
			throw new NotSupportedException();
		this.removeItem(index);
	}

	protected void removeItem(int index)
	{
		this.theList.removeAt(index);
	}

	/* ********************************************************
	 * 扩展方法
	 * ********************************************************/
	protected IList!(T) items()
	{
		return theList;
	}
}